#ifndef __DOTFONT_IMPL_H__
#define __DOTFONT_IMPL_H__

#include "dotfont.h"

namespace dotfont{

using Gdiplus::ColorPalette;

class DotFont_impl :
	public DotFont
{
public:

	DotFont_impl(void);
	virtual ~DotFont_impl(void);

	virtual bool generate(const wchar_t* CharSet, 
		const wchar_t* FontName, float FontSize, Style S, const PixelFormat& pf, 
		const Size& EntrySize, const PointF& EntryOffset,
		int nEntryRow, int nEntryColumn,
		DWORD FontColor, DWORD BgColor, bool Antialiase);

	virtual bool generateWithStroke( const wchar_t* CharSet, const wchar_t* FontName, float FontSize, 
		Style S, const PixelFormat& pf, const Size& EntrySize, DWORD StrokeColor,
		const PointF& EntryOffset,
		int nEntryRow, int nEntryColumn,
		DWORD FontColor, DWORD BgColor, bool Antialiase);


	virtual void dump(bool ShowGrid, const wchar_t* Prefix, const wchar_t* Path);

	virtual const wchar_t* getError()
		{ return errmsg.c_str(); }

protected:

	class Range
	{
	public:
		Range(UINT32 From, UINT32 To)
			: from(From), to(To)
		{}

		Range(const Range& cr)
			: from(cr.from), to(cr.to)
		{}

		bool operator== (const Range& cr) const
		{
			return from == cr.from && to == cr.to;
		}

		bool inRange(UINT32 V) const
		{
			return V >= from && V < to;
		}

	private:
		UINT32 from, to;
	};

	class Block
	{
	public:
		Block(const Range& Range, const Size& EntrySize, const Size& BmpSize, int Bpp, const Size& BmpSizeInEntry)
			: range(Range), entrySize(EntrySize), bmpSize(BmpSize), bpp(Bpp), bmpSizeInEntry(BmpSizeInEntry)
		{
			bmpData = new BYTE[bmpSize.Width * bmpSize.Height * bpp];
			assert(bmpData);
		}

		~Block()
		{
			delete bmpData;
		}

		BYTE* getRawData()
		{ return bmpData; }

		const BYTE* getRawData() const
		{ return bmpData; }

		const Size& getEntrySize() const
		{ return entrySize; }

		const Size& getBmpSize() const
		{ return bmpSize; }

		const Size& getBmpSizeInEntry() const
		{ return bmpSizeInEntry; }

		const Range& getRange() const
		{ return range; }

	private:
		Block(const Block& V) : range(0xCCCCCCCC, 0xCCCCCCCC) {}

		Range range;
		Size entrySize;
		Size bmpSize;
		int bpp;
		Size bmpSizeInEntry;
		BYTE* bmpData;
	};

protected:
	inline size_t getBpp();

private:
	wstring errmsg;

	wstring fontName;
	float fontSize;
	Style style;
	PixelFormat pixelFormat;
	Size entrySize;
	ColorPalette* palette;
	
	vector<Block*> blocks;
};

} // namespace dotfont


#endif // __DOTFONT_IMPL_H__




